package token

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"gitee.com/chejiangyi/bsfgo/core/base2"
	"gitee.com/chejiangyi/bsfgo/core/utils"
	"time"
)

type HashTokenStrategy struct {
}

// 生成带时间戳的哈希Token
func (m *HashTokenStrategy) ToToken(userID string) string {
	// 创建过期时间戳
	expiresAt := time.Now().Add(time.Duration(base2.BsfConfigInstance.GetTokenTTLSeconds()) * time.Second).Unix()
	// 创建HMAC哈希
	h := hmac.New(sha256.New, []byte(base2.BsfConfigInstance.GetTokenSecretKey()))
	data := fmt.Sprintf("%s:%d", userID, expiresAt)
	h.Write([]byte(data))
	// 生成Token格式: userID:expiresAt:signature
	token := fmt.Sprintf("%s:%d:%s", userID, expiresAt, hex.EncodeToString(h.Sum(nil)))
	return token
}

// ValidateHashedToken 验证哈希Token
func (m *HashTokenStrategy) FromToken(token string) string {
	// 解析Token
	parts := splitToken(token)
	if len(parts) != 3 {
		panic(base2.NewBsfError(fmt.Sprintf("token格式不正确:%v", token)))
	}
	userID := parts[0]
	expiresAtStr := parts[1]
	signature := parts[2]
	// 验证过期时间
	expiresAt := utils.ConvertUtil.ToInt64(expiresAtStr)
	if time.Now().Unix() > expiresAt {
		panic(base2.NewBsfError(fmt.Sprintf("token已过期:%v", token)))
	}
	// 重新计算签名进行验证
	h := hmac.New(sha256.New, []byte(base2.BsfConfigInstance.GetTokenSecretKey()))
	data := fmt.Sprintf("%s:%s", userID, expiresAtStr)
	h.Write([]byte(data))
	expectedSignature := hex.EncodeToString(h.Sum(nil))
	if !hmac.Equal([]byte(signature), []byte(expectedSignature)) {
		panic(base2.NewBsfError(fmt.Sprintf("token签名异常:%v", token)))
	}
	return userID
}

func splitToken(token string) []string {
	// 简单分割实现，实际应用中可能需要更复杂的解析
	var parts []string
	last := 0
	for i, c := range token {
		if c == ':' {
			parts = append(parts, token[last:i])
			last = i + 1
		}
	}
	if last < len(token) {
		parts = append(parts, token[last:])
	}
	return parts
}
